
import os

import pygame.display
import pygame.font

import jukebox.widget
from jukebox.Album import Album

TESTING = True
ALBUMDIR = '/home/mike/sound/albums/'
ALBUM_AREA = 500
ALBUM_PADDING = 5

## FIXME 
def drawroundyrect( surface, color, rect, width=1 ):
    pygame.draw.rect(surface, color, rect, width)


    
class Quit(Exception):
    pass

class Main:

    def __init__(self):
        self.screen = pygame.display.set_mode((1024,768))

        self.font = pygame.font.Font('/usr/share/fonts/truetype/mike-downloaded/px10.ttf',35)
        self.numberfont = pygame.font.Font('/usr/share/fonts/truetype/mike-downloaded/transistor.ttf',35)
        self.tinyfont = pygame.font.Font('/usr/share/fonts/truetype/mike-downloaded/px10.ttf',15)
        self.widgets = {}
        self.albumcovers = []

        
        self.textinput = False
        self.text = ''
        self.cursoron = pygame.image.load('media/cursor-on.jpeg').convert()
        self.cursoroff = pygame.image.load('media/cursor-off.jpeg').convert()
        self.cursor = True
        self.cursorcount = 0
        self.prompt = self.font.render("INPUT: ", True, (0,255,0), (0,0,0))

        self.dim = pygame.Surface( (1024,768))
        self.dim.fill( (0,0,0) )
        pygame.draw.rect(self.dim, (0,128,0), (0,300,1024,200))
        self.dim.set_alpha(128)

        # FIXME; merge somehow?
        self.selected = None
        self.queue = []
        self.trackqueue = []
        self.oldqueue = None
        self.oldtrackqueue = None

        self.mouseposition = (0,0)
        self.nowplaying = None

    def addWidget(self,w,layer=0):
        if self.widgets.has_key(layer):
            self.widgets[layer].append(w)
        else:
            self.widgets[layer] = [w]

    def removeWidget(self,w):
        for k in self.widgets.keys():
            try:
                self.widgets[k].remove(w)
            except ValueError:
                pass
                

    def getTextInput(self,prompt):
        self.prompt = self.font.render(prompt, True, (0,255,0), (0,0,0))
        self.textinput = True
        self.text = ''

    def skipTrack(self):
        pass

    def playTrack(self,t):
        pygame.music

    def playAlbum(self,album):
        if self.nowplaying:
            raise "already playing!"
        self.nowplaylaying = (album,1)
        self.playTrack(album.track(1))
        
            

    def checkQueue(self):
        if self.album.state:
            if not self.nowplaying:
                if len(self.queue):
                    a = self.queue[0]
                    self.queue = self.queue[1:]
                    self.playAlbum(a)
                    self.layoutAlbums()

    def processEvent(self,e):
        if e.type == pygame.NOEVENT:
            return

        elif e.type == pygame.QUIT:
            raise Quit()

        elif e.type == pygame.USEREVENT:
            if e.juketype == 'ALBUM_CLICKED':
                if self.album.state:
                    a = e.cover
                    if a in self.queue:
                        self.queue.remove(a)
                        a.addBehavior(jukebox.widget.Resize(jukebox.widget.MEDIUM_SIZE,5))
                        self.skipTrack()
                        
                    else:
                        a.unSelect()
                        a.addBehavior(jukebox.widget.Fly(len(self.queue)*(jukebox.widget.SMALL_SIZE[0]+5) + 5,600))
                        a.addBehavior(jukebox.widget.Resize(jukebox.widget.SMALL_SIZE,5))
                        self.queue.append( e.cover )
                        if len(self.queue) == 1:
                            pygame.event.post(pygame.event.Event(pygame.USEREVENT,
                                                                 {'juketype':'CHECK_QUEUE'}
                                                                 ))

                    self.layoutAlbums()

                else:
                    # track-queue mode
                    if self.selected:
                        self.selected.unSelect()

                    if self.selected == e.cover:
                        self.selected = None
                    else:
                        self.selected = e.cover
                        self.selected.select()

            elif e.juketype == 'TRACK_CLICKED':
                t = e.track
                e.label.enabled = False
                t.queued = True
                self.trackqueue.append(t)
                print "LOC",e.label.location
                tc = jukebox.widget.TrackCover(e.cover,e.track,self.numberfont,self.mouseposition[0]-jukebox.widget.SMALL_SIZE[0]/2,self.mouseposition[1]-jukebox.widget.SMALL_SIZE[0]/2,5)
                tc.addBehavior(jukebox.widget.SlowFly((jukebox.widget.SMALL_SIZE[0]+5)*len(self.trackqueue),600))
                if len(self.trackqueue) == 1:
                    pygame.event.post(pygame.event.Event(pygame.USEREVENT,
                                                         {'juketype':'CHECK_QUEUE'}
                                                         ))

            elif e.juketype == 'CHECK_QUEUE':
                self.checkQueue()

            elif e.juketype == 'BUTTON_CLICKED':
                b = e.button
                if b == self.track:
                    for a in self.queue:
                        a.addBehavior(jukebox.widget.Resize(jukebox.widget.MEDIUM_SIZE,5))
                    self.oldqueue = self.queue
                    self.queue = []
                    self.layoutAlbums()

                elif b == self.album:
                    if self.selected:
                        self.selected.unSelect();
                        self.selected = None
                    if self.oldqueue:
                        self.queue = self.oldqueue
                        for a in self.queue:
                            a.addBehavior(jukebox.widget.Resize(jukebox.widget.SMALL_SIZE,5))
                        self.layoutAlbums()
                        self.oldqueue = None

            else:
                print "UNKNOWN userevent:",e.juketype

        elif self.textinput and e.type == pygame.KEYUP:
            if e.key == 13:
                self.textinput = False
            elif e.key == 8:
                self.text = self.text[:-1]
            elif e.key > 13 and e.key < 256:
                self.text = self.text + chr(e.key).upper()

        elif e.type == pygame.MOUSEMOTION:
            self.mouseposition = e.pos

        if not self.textinput:
            keys = self.widgets.keys()
            keys.sort()
            keys.reverse()
            try:
                for k in keys:
                    for x in self.widgets[k]:
                        if hasattr(x,'mouseIn'):
                            x.mouseIn = False
                    for x in self.widgets[k]:
                        if x.processEvent(e):
                            #print "processed",e,"with",x,"at layer",k
                            raise Quit()
            except Quit:
                pass

            #FIXME
            if e.type == pygame.MOUSEMOTION:
                if e.pos[0] > 1000:
                    self.scrollX = self.scrollX + 10
                elif e.pos[0] < 24:
                    self.scrollX = self.scrollX - 10

    def drawTextInput(self):
        self.screen.blit(self.dim,(0,0))
        t = self.font.render(self.text, True, (0,200,0), (0,0,0))

        PADDING = 5
        width = self.prompt.get_size()[0] + (2*PADDING) + t.get_size()[0]
        x = (1024 / 2) - (width/2)


        pygame.draw.rect(self.screen,(0,0,0), (x, 345, self.prompt.get_size()[0] + t.get_size()[0] + PADDING + PADDING + 10 + self.cursoron.get_size()[0], self.prompt.get_size()[1] + PADDING + PADDING))
        drawroundyrect(self.screen, (0,255,0), (x, 345, self.prompt.get_size()[0] + t.get_size()[0] + PADDING + PADDING + 10 + self.cursoron.get_size()[0], self.prompt.get_size()[1] + PADDING + PADDING), 1)
        
        self.screen.blit(self.prompt, (x + PADDING,350))
        self.screen.blit(t, (x + self.prompt.get_size()[0] + 2*PADDING, 350))
        if self.cursor:
            self.screen.blit(self.cursoron, (x + self.prompt.get_size()[0] + PADDING + t.get_size()[0] + PADDING, 350))
        else:
            self.screen.blit(self.cursoroff, (x + self.prompt.get_size()[0] + PADDING + t.get_size()[0] + PADDING, 350))
        self.cursorcount = self.cursorcount + 1
        if self.cursorcount > 5:
            self.cursorcount = 0
            self.cursor = not self.cursor

    def layoutAlbums(self):

        a = self.albumcovers[0]
        rows = int(ALBUM_AREA / jukebox.widget.MEDIUM_SIZE[1])
        padding = (ALBUM_AREA - (rows*jukebox.widget.MEDIUM_SIZE[1])) / rows
        
        x = padding
        r = 0
        for a in self.albumcovers:
            if a in self.queue:
                continue
            y = r * (jukebox.widget.MEDIUM_SIZE[1] + padding) + padding
            a.addBehavior(jukebox.widget.Fly(x,y))

            r = r + 1
            if r >= rows:
                r = 0
                x = x + jukebox.widget.MEDIUM_SIZE[0] + padding

        x = 5
        for a in self.queue:
            a.addBehavior(jukebox.widget.Fly(x,600))
            x = x + jukebox.widget.SMALL_SIZE[0] + 5
        

    def setup(self):
        jukebox.widget.registrars.append(self)
        self.albums = []
        for x in os.listdir(ALBUMDIR)[:10]:
            dir = os.path.join(ALBUMDIR,x)
            if os.path.isfile(os.path.join(dir,"art.jpeg")):
                a = Album(dir)
                self.albums.append(a)
                c = jukebox.widget.AlbumCover(a,self.tinyfont)
                #self.widgets.append(c)
                self.albumcovers.append(c)

        self.layoutAlbums()

        foo = jukebox.widget.Label( (10,730), "play mode:", self.font, (0,255,0))
        foo.fixed = True
        #self.widgets.append(foo)
        self.shuffle = jukebox.widget.TextRadioButton( (10 + foo.size[0] + 10,730), "shuffle", self.font )
        self.shuffle.fixed = True
        self.sequential = jukebox.widget.TextRadioButton( (10 + foo.size[0] + 10 + self.shuffle.size[0] + 10,730),
                                           "sequential", self.font)
        self.sequential.fixed = True
        self.shuffle.addToGroup(self.sequential)
        self.sequential.clicked()
        #self.widgets.append(self.shuffle)
        #self.widgets.append(self.sequential)

        foo = jukebox.widget.Label( (10,680), "queue mode:", self.font, (0,255,0))
        foo.fixed = True
        #self.widgets.append(foo)
        self.album = jukebox.widget.TextRadioButton( (10 + foo.size[0] + 10,680), "album", self.font)
        self.album.fixed = True
        self.track = jukebox.widget.TextRadioButton( (10 + foo.size[0] + 10 + self.album.size[0] + 10,680), "track", self.font)
        self.track.fixed = True
        self.album.addToGroup(self.track)
        self.album.clicked()
        self.track.clicked()
        #self.widgets.append(self.album)
        #self.widgets.append(self.track)

        
    def mainloop(self):
        self.setup()
        self.scrollX = 0
        
        while True:
            self.screen.fill( (0,0,0) )
            over = None
            for k in self.widgets.keys():
                for x in self.widgets[k]:
                    x.animate()
                    x.draw(self.screen,self.scrollX,0)
                    if isinstance(x,jukebox.widget.AlbumCover) and x.mouseIn:
                        over = x

            if over:
                over.draw(self.screen,self.scrollX,0)
            if self.selected:
                self.selected.draw(self.screen,self.scrollX,0)

            if self.textinput:
                self.drawTextInput()

            pygame.display.update()

            e = pygame.event.poll()
            if e.type != pygame.NOEVENT:
                self.processEvent(e)
                while pygame.event.peek((pygame.MOUSEMOTION,pygame.MOUSEBUTTONUP,pygame.MOUSEBUTTONDOWN)):
                    self.processEvent(pygame.event.poll())

            #time.sleep(0.01)




def go():
    print "starting"
    pygame.font.init()
    pygame.display.init()
    print "pygame initialized; starting mainloop"
    
    m = Main()

    if 0:#TESTING:
        m.getTextInput("Enter Something: ")
    
    try:
        m.mainloop()
    except Quit:
        print "exiting..."
